# -*- coding: utf-8 -*-
"""
API响应模式定义
提供标准化的响应格式
"""

from typing import Optional, Any, Dict, Generic, TypeVar
from pydantic import BaseModel, Field
from datetime import datetime

T = TypeVar('T')


class BaseResponse(BaseModel, Generic[T]):
    """基础响应模型"""
    code: int = Field(..., description="响应状态码")
    message: str = Field(..., description="响应消息")
    data: Optional[T] = Field(None, description="响应数据")
    timestamp: datetime = Field(default_factory=datetime.now, description="响应时间")
    success: bool = Field(..., description="是否成功")
    detail: Optional[str] = Field(None, description="详细信息")
    request_id: Optional[str] = Field(None, description="请求ID")

    class Config:
        json_encoders = {
            datetime: lambda v: v.isoformat()
        }


class SuccessResponse(BaseResponse[T]):
    """成功响应模型"""
    code: int = Field(default=200, description="成功状态码")
    success: bool = Field(default=True, description="成功标识")


class ErrorResponse(BaseResponse[None]):
    """错误响应模型"""
    success: bool = Field(default=False, description="失败标识")
    data: None = Field(default=None, description="错误响应无数据")


class ValidationErrorDetail(BaseModel):
    """验证错误详情"""
    message: str = Field(..., description="错误消息")
    type: str = Field(..., description="错误类型")
    input: Optional[Any] = Field(None, description="输入值")


class ValidationErrorResponse(ErrorResponse):
    """验证错误响应"""
    validation_errors: Optional[Dict[str, ValidationErrorDetail]] = Field(None, description="验证错误详情")


class PaginatedData(BaseModel, Generic[T]):
    """分页数据模型"""
    items: list[T] = Field(..., description="数据项列表")
    total: int = Field(..., description="总数量")
    page: int = Field(..., description="当前页码")
    size: int = Field(..., description="页面大小")
    pages: int = Field(..., description="总页数")
    has_next: bool = Field(..., description="是否有下一页")
    has_prev: bool = Field(..., description="是否有上一页")

    @classmethod
    def create(
        cls,
        items: list[T],
        total: int,
        page: int,
        size: int
    ) -> "PaginatedData[T]":
        """创建分页数据"""
        pages = (total + size - 1) // size  # 向上取整
        return cls(
            items=items,
            total=total,
            page=page,
            size=size,
            pages=pages,
            has_next=page < pages,
            has_prev=page > 1
        )


class PaginatedResponse(SuccessResponse[PaginatedData[T]]):
    """分页响应模型"""
    pass


# 常用响应类型别名
StringResponse = SuccessResponse[str]
DictResponse = SuccessResponse[Dict[str, Any]]
ListResponse = SuccessResponse[list]
BoolResponse = SuccessResponse[bool]
IntResponse = SuccessResponse[int] 